/**
 * 
 */
package com.zdy.im.tio.command;


import com.zdy.im.common.exception.ImException;
import com.zdy.im.tio.TioServerConfig;
import com.zdy.im.tio.packets.SocketResponseVo;
import com.zdy.im.core.*;
import org.eclipse.jetty.server.session.SessionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
import org.tio.core.intf.Packet;
import org.tio.utils.json.Json;

import java.util.Objects;

/**
 * 版本: [1.0]
 * 功能说明: 
 * @Author 作者 : zdy
 * @CreateDate 创建时间: 2021-02-30
 */
public class ProtocolManager implements ImConst {
	
	private static Logger logger = LoggerFactory.getLogger(ProtocolManager.class);
	


	public static class Converter{

		/**
		 * 功能描述：[转换不同协议响应包]
		 * @author：WChao 创建时间: 2017年9月21日 下午3:21:54
		 * @param respBody 响应消息体
		 * @param imChannelContext IM通道上下文
		 * @return
		 *
		 */
		public static ImPacket responsePacket(SocketResponseVo respBody, ChannelContext imChannelContext)throws ImException {
			if(Objects.isNull(respBody)) {
				throw new ImException("响应包体不能为空!");
			}
			return responsePacket(respBody.toByte(), respBody.getCommand(), imChannelContext);
		}

		/**
		 * 功能描述：[转换不同协议响应包]
		 * @param body 消息体字节
		 * @param command 命令码
		 * @param imChannelContext IM通道上下文
		 * @return
		 * @throws ImException
		 */
		public static ImPacket responsePacket(byte[] body, ICommand command, ChannelContext imChannelContext)throws ImException{
			return getConverter(body, command, imChannelContext);
		}


		/**
		 * 功能描述：[转换不同协议响应包]
		 * @author：WChao 创建时间: 2017年9月21日 下午3:21:54
		 * @param imPacket 消息包
		 * @param command 命令码
		 * @param channelContext IM通道上下文
		 * @return
		 *
		 */
		public static ImPacket responsePacket(ImPacket imPacket,ICommand command, ChannelContext channelContext)throws ImException{
			return  getConverter(imPacket.getBody(), command, channelContext);
		}



		public static SessionContext getSessionContext(ChannelContext channelContext){
			return (SessionContext)channelContext.getAttribute(Key.IM_CHANNEL_SESSION_CONTEXT_KEY);
		}

		/**
		 * 通过通道获取当前通道协议
		 * @param channelContext IM通道上下文
		 * @return
		 * @throws ImException
		 */
		private static ImPacket getConverter(byte[] body,ICommand command, ChannelContext channelContext) throws ImException{
			ImPacket packet =  ImPacket.build(command,body);
			packet.setImChannelContext(channelContext);
			return packet;
		}

	}

	public static class ResponsePacket{
		/**
		 * 数据格式不正确响应包
		 * @param channelContext
		 * @return imPacket
		 * @throws ImException
		 */
		public static Packet dataInCorrect(ChannelContext channelContext) throws ImException {
			SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(Command.COMMAND_CHAT_ONE_RESP, ImStatus.C10002);
			ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, channelContext);
			respPacket.setStatus(ImStatus.C10002);
			return respPacket;
		}

		/**
		 * 数据格式不正确响应包
		 * @param channelContext
		 * @return imPacket
		 * @throws ImException
		 */
		public static Packet dataToSendFailed(ChannelContext channelContext) throws ImException {
			SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(Command.COMMAND_CHAT_ONE_RESP, ImStatus.C10022);
			ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, channelContext);
			respPacket.setStatus(ImStatus.C10002);
			return respPacket;
		}

		/**
		 * 数据格式不正确响应包
		 * @param channelContext
		 * @return imPacket
		 * @throws ImException
		 */
		public static Packet dataToExceptionFailed(ChannelContext channelContext){
			try {
				SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(Command.COMMAND_UNKNOW, ImStatus.C10022);
				ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, channelContext);
				respPacket.setStatus(ImStatus.C10002);
				return respPacket;
			}catch (Exception e){
				e.printStackTrace();
			}return null;

		}


		/**
		 * 发送成功响应包
		 * @param imChannelContext
		 * @return imPacket
		 * @throws ImException
		 */
		public static ImPacket  success(ChannelContext imChannelContext) throws ImException{
			SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(Command.COMMAND_CHAT_ONE_RESP, ImStatus.C10000);
			ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, imChannelContext);
			respPacket.setStatus(ImStatus.C10000);
			return respPacket;
		}

		/**
		 * 用户不在线响应包
		 * @param imChannelContext
		 * @return
		 * @throws ImException
		 */
		public static ImPacket  offline(ChannelContext imChannelContext) throws ImException{
			SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(Command.COMMAND_CHAT_ONE_RESP,ImStatus.C10001);
			ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, imChannelContext);
			respPacket.setStatus(ImStatus.C10001);
			return respPacket;
		}

		/**
		 * 发送成功响应包
		 * @param imChannelContext
		 * @return imPacket
		 * @throws ImException
		 */
		public static ImPacket  success(ChannelContext imChannelContext,ICommand iCommand) throws ImException{
			return success(imChannelContext,iCommand,null);
		}
		/**
		 * 发送成功响应包
		 * @param imChannelContext
		 * @return imPacket
		 * @throws ImException
		 */
		public static ImPacket  success(ChannelContext imChannelContext,ICommand iCommand,Object data) throws ImException{
			SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(iCommand, ImStatus.C10000);
			ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, imChannelContext);
			if(data != null){
				try {
					String response = Json.toJsonAboutNull(data);
					byte[] body = response.getBytes(TioServerConfig.CHARSET);
					respPacket.setBody(body);
				}catch (Exception e){
					e.printStackTrace();
				}
			}
			respPacket.setStatus(ImStatus.C10000);
			return respPacket;
		}
		/**
		 * 用户不在线响应包
		 * @param imChannelContext
		 * @return
		 * @throws ImException
		 */
		public static ImPacket  offline(ChannelContext imChannelContext,ICommand iCommand) throws ImException{
			SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(iCommand,ImStatus.C10001);
			ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, imChannelContext);
			respPacket.setStatus(ImStatus.C10001);
			return respPacket;
		}
		/**
		 * 数据格式不正确响应包
		 * @param channelContext
		 * @return imPacket
		 * @throws ImException
		 */
		public static Packet dataInCorrect(ChannelContext channelContext,ICommand iCommand) throws ImException {
			SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(iCommand, ImStatus.C10002);
			ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, channelContext);
			respPacket.setStatus(ImStatus.C10002);
			return respPacket;
		}

		/**
		 * 数据格式不正确响应包
		 * @param channelContext
		 * @return imPacket
		 * @throws ImException
		 */
		public static Packet dataToSendFailed(ChannelContext channelContext, ICommand iCommand, Status imStatus) throws ImException {
			SocketResponseVo chatDataInCorrectRespPacket = new SocketResponseVo(iCommand,imStatus);
			ImPacket respPacket = Converter.responsePacket(chatDataInCorrectRespPacket, channelContext);
			respPacket.setStatus(ImStatus.C10002);
			return respPacket;
		}
	}
}
